use serde::Serialize;
use serde_json::to_string_pretty;
use sha2::{Sha256, Digest};
use ring::signature::{self, KeyPair};
use std::time::{SystemTime, UNIX_EPOCH};

// 获取当前时间戳
fn get_current_timestamp() -> u64 {
    SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("Time went backwards")
        .as_secs()
}

// 第一部分：哈希函数应用
fn hash_demo() {
    println!("===== 哈希函数应用 =====");
    
    // 字符串哈希
    let message = "Hello, Blockchain!";
    let mut hasher = Sha256::new();
    hasher.update(message.as_bytes());
    let result = hasher.finalize();
    let hex_dig = format!("{:x}", result);
    
    println!("字符串哈希示例:");
    println!("原始数据: {}", message);
    println!("SHA-256哈希值: {}", hex_dig);
    println!("哈希值长度: {} 字符 ({} 位)", hex_dig.len(), hex_dig.len() * 4);
    println!();
    
    // 交易哈希（使用结构体）
    #[derive(Serialize, Debug, Clone)]
    struct Transaction {
        sender: String,
        recipient: String,
        amount: f64,
        timestamp: u64,
    }
    
    let transaction = Transaction {
        sender: "wallet1".to_string(),
        recipient: "wallet2".to_string(),
        amount: 10.5,
        timestamp: get_current_timestamp(),
    };
    
    // 转换为JSON并排序键
    let tx_json = serde_json::to_string(&transaction).unwrap();
    let parsed: serde_json::Value = serde_json::from_str(&tx_json).unwrap();
    
    // 排序键
    let sorted_tx = sort_json_keys(&parsed);
    let sorted_tx_json = to_string_pretty(&sorted_tx).unwrap();
    
    // 计算哈希
    let mut tx_hasher = Sha256::new();
    tx_hasher.update(sorted_tx_json.as_bytes());
    let tx_hash_result = tx_hasher.finalize();
    let tx_hash = format!("{:x}", tx_hash_result);
    
    println!("交易哈希示例:");
    println!("原始交易: {:?}", transaction);
    println!("JSON序列化后: {}", sorted_tx_json);
    println!("交易哈希值: {}", tx_hash);
    println!();
    
    // 演示雪崩效应
    let message1 = "blockchain is amazing";
    let message2 = "blockchain is amaziny"; // 最后一个字符不同
    
    let mut hasher1 = Sha256::new();
    hasher1.update(message1.as_bytes());
    let hash1 = format!("{:x}", hasher1.finalize());
    
    let mut hasher2 = Sha256::new();
    hasher2.update(message2.as_bytes());
    let hash2 = format!("{:x}", hasher2.finalize());
    
    println!("雪崩效应示例:");
    println!("消息1: {}", message1);
    println!("消息2: {}", message2);
    println!("哈希1: {}", hash1);
    println!("哈希2: {}", hash2);
    
    // 计算不同位数
    let diff_bits = hash1.chars().zip(hash2.chars())
        .filter(|(c1, c2)| c1 != c2)
        .count() * 4;
    println!("不同位数: ~{} 位 (约占总位数的 {:.1}%)", 
             diff_bits, diff_bits as f64 / 256.0 * 100.0);
}

// 辅助函数：排序JSON键
fn sort_json_keys(value: &serde_json::Value) -> serde_json::Value {
    match value {
        serde_json::Value::Object(obj) => {
            let mut sorted = serde_json::Map::new();
            let mut keys: Vec<_> = obj.keys().collect();
            keys.sort();
            
            for key in keys {
                sorted.insert(key.clone(), sort_json_keys(&obj[key]));
            }
            
            serde_json::Value::Object(sorted)
        },
        serde_json::Value::Array(arr) => {
            serde_json::Value::Array(
                arr.iter().map(sort_json_keys).collect()
            )
        },
        _ => value.clone(),
    }
}

// 第二部分：简易数字签名系统
fn digital_signature_demo() {
    println!("\n===== 数字签名系统 =====");
    
    struct SimpleWallet {
        private_key: Vec<u8>,
        public_key: Vec<u8>,
        address: String,
    }
    
    impl SimpleWallet {
        fn new() -> Self {
            // 生成椭圆曲线密钥对
            let rng = ring::rand::SystemRandom::new();
            let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng)
                .expect("Failed to generate key pair");
            
            let key_pair = signature::Ed25519KeyPair::from_pkcs8(pkcs8_bytes.as_ref())
                .expect("Failed to parse key pair");
            
            let private_key = pkcs8_bytes.as_ref().to_vec();
            let public_key = key_pair.public_key().as_ref().to_vec();
            
            // 生成钱包地址（简化版）
            let mut address_hasher = Sha256::new();
            address_hasher.update(&public_key);
            let address_hash = address_hasher.finalize();
            let address = format!("{:x}", address_hash).chars().take(20).collect();
            
            Self {
                private_key,
                public_key,
                address,
            }
        }
        
        fn sign_message(&self, message: &str) -> Vec<u8> {
            let key_pair = signature::Ed25519KeyPair::from_pkcs8(&self.private_key)
                .expect("Failed to parse key pair");
            
            key_pair.sign(message.as_bytes()).as_ref().to_vec()
        }
        
        fn verify_signature(message: &str, signature: &[u8], public_key: &[u8]) -> bool {
            let public_key_bytes = signature::UnparsedPublicKey::new(
                &signature::ED25519,
                public_key
            );
            
            public_key_bytes.verify(message.as_bytes(), signature).is_ok()
        }
        
        fn get_public_key_bytes(&self) -> &[u8] {
            &self.public_key
        }
    }
    
    // 创建两个钱包
    let alice = SimpleWallet::new();
    let bob = SimpleWallet::new();
    
    println!("Alice的钱包地址: {}", alice.address);
    println!("Bob的钱包地址: {}", bob.address);
    println!();
    
    // Alice创建一个交易
    #[derive(Serialize, Debug, Clone)]
    struct Transaction {
        sender: String,
        recipient: String,
        amount: f64,
        timestamp: u64,
    }
    
    let transaction = Transaction {
        sender: alice.address.clone(),
        recipient: bob.address.clone(),
        amount: 5.0,
        timestamp: get_current_timestamp(),
    };
    
    // 将交易转换为JSON并排序键
    let tx_json = serde_json::to_string(&transaction).unwrap();
    let parsed: serde_json::Value = serde_json::from_str(&tx_json).unwrap();
    let sorted_tx = sort_json_keys(&parsed);
    let sorted_tx_json = to_string_pretty(&sorted_tx).unwrap();
    
    println!("交易内容: {}", sorted_tx_json);
    println!();
    
    // Alice对交易进行签名
    let signature = alice.sign_message(&sorted_tx_json);
    println!("交易签名: {}... (长度: {} 字节)", 
             hex::encode(&signature[..50]), signature.len());
    println!();
    
    // 验证签名
    let is_valid = SimpleWallet::verify_signature(
        &sorted_tx_json, 
        &signature, 
        alice.get_public_key_bytes()
    );
    println!("签名验证结果: {}", if is_valid { "有效" } else { "无效" });
    println!();
    
    // 演示篡改交易后的验证
    let mut tampered_transaction = transaction.clone();
    tampered_transaction.amount = 10.0; // 篡改金额
    
    let tampered_tx_json = serde_json::to_string(&tampered_transaction).unwrap();
    let parsed_tampered: serde_json::Value = serde_json::from_str(&tampered_tx_json).unwrap();
    let sorted_tampered_tx = sort_json_keys(&parsed_tampered);
    let sorted_tampered_tx_json = to_string_pretty(&sorted_tampered_tx).unwrap();
    
    println!("篡改后的交易: {}", sorted_tampered_tx_json);
    
    // 使用同一签名验证篡改后的交易
    let is_valid_tampered = SimpleWallet::verify_signature(
        &sorted_tampered_tx_json, 
        &signature, 
        alice.get_public_key_bytes()
    );
    println!("篡改后签名验证结果: {}", if is_valid_tampered { "有效" } else { "无效" });
    println!();
    
    // 演示不同私钥签名的验证
    let other_signature = bob.sign_message(&sorted_tx_json); // Bob用自己的私钥签名Alice的交易
    // 使用Alice的公钥验证Bob的签名（应该失败）
    let is_valid_wrong_signer = SimpleWallet::verify_signature(
        &sorted_tx_json, 
        &other_signature, 
        alice.get_public_key_bytes()
    );
    println!("非交易发起者签名验证: {}", 
             if is_valid_wrong_signer { "有效（错误）" } else { "无效（正确）" });
}

fn main() {
    // 哈希函数演示
    hash_demo();
    
    // 数字签名演示
    digital_signature_demo();
}
